#!/usr/bin/env python3
import sys
import os
import re
import logging

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
logger = logging.getLogger('MainFinder')

def find_main_functions(directory):
    """Find all main functions in C/C++ files in the given directory."""
    if not os.path.isdir(directory):
        logger.error(f"Directory not found: {directory}")
        return
    
    # Main function patterns
    main_patterns = [
        # Standard patterns
        (r'int\s+main\s*\(\s*int\s+\w+\s*,\s*char\s*\*+\s*\w+\[\s*\]\s*\)\s*\{', "Standard main with argc, argv[]"),
        (r'int\s+main\s*\(\s*int\s+\w+\s*,\s*char\s*\*+\s*\*+\s*\w+\s*\)\s*\{', "Standard main with argc, **argv"),
        (r'int\s+main\s*\(\s*void\s*\)\s*\{', "Main with void"),
        (r'int\s+main\s*\(\s*\)\s*\{', "Simple main()"),
        # More lenient pattern
        (r'int\s+main\s*\([^)]*\)\s*\{', "Any main function")
    ]
    
    # Find all C/C++ files
    found_main = False
    cpp_files = []
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(('.c', '.cpp', '.cxx', '.cc')):
                cpp_files.append(os.path.join(root, file))
    
    logger.info(f"Found {len(cpp_files)} C/C++ files to search")
    
    # Check each file for main functions
    for file_path in cpp_files:
        try:
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
                content = file.read()
                
                # Check each pattern
                for pattern, desc in main_patterns:
                    matches = list(re.finditer(pattern, content, re.MULTILINE))
                    if matches:
                        found_main = True
                        for match in matches:
                            # Get line number
                            line_num = content[:match.start()].count('\n') + 1
                            
                            # Get matched text and surrounding context
                            start = max(0, match.start() - 50)
                            end = min(len(content), match.end() + 50)
                            context = content[start:end].replace('\n', ' ')
                            
                            logger.info(f"Found main function ({desc}) in {file_path} at line {line_num}")
                            logger.info(f"Context: ...{context}...")
                            
                            # If we found a main function, get the full function body
                            # (this is a simplified version and won't handle all cases correctly)
                            start_pos = match.start()
                            pos = match.end()
                            brace_count = 1
                            
                            while pos < len(content) and brace_count > 0:
                                if content[pos] == '{':
                                    brace_count += 1
                                elif content[pos] == '}':
                                    brace_count -= 1
                                pos += 1
                            
                            if brace_count == 0:
                                # Extract beginning of function
                                main_start = content[start_pos:start_pos+200].replace('\n', ' ')
                                logger.info(f"Function starts with: {main_start}...")
        except Exception as e:
            logger.error(f"Error reading file {file_path}: {e}")
    
    if not found_main:
        logger.warning("No main function found in any file!")
        
        # Look for files named main.c or main.cpp
        main_files = [f for f in cpp_files if os.path.basename(f).lower().startswith('main.')]
        if main_files:
            logger.info(f"Found {len(main_files)} files named main.*:")
            for main_file in main_files:
                logger.info(f" - {main_file}")
                
                # Look for 'main' string in these files
                try:
                    with open(main_file, 'r', encoding='utf-8', errors='ignore') as file:
                        content = file.read()
                        matches = list(re.finditer(r'\bmain\b', content))
                        if matches:
                            logger.info(f"   Found {len(matches)} references to 'main'")
                            for i, match in enumerate(matches[:5]):  # Show first 5 matches
                                line_start = content.rfind('\n', 0, match.start()) + 1
                                line_end = content.find('\n', match.end())
                                if line_end == -1:
                                    line_end = len(content)
                                line = content[line_start:line_end].strip()
                                logger.info(f"   {i+1}: {line}")
                except Exception as e:
                    logger.error(f"Error analyzing file {main_file}: {e}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        logger.error("Usage: python find_main.py <directory>")
        sys.exit(1)
    
    find_main_functions(sys.argv[1]) 